package org.budo.time.impl;

import java.io.Serializable;
import java.util.Date;

import org.budo.time.Time;
import org.budo.time.TimePoint;
import org.budo.time.TimeSpan;

/**
 * 表示一个时间段
 * 
 * @author limingwei
 */
public class BudoTimeSpan implements Serializable, TimeSpan {
    private static final long serialVersionUID = 4355045459032295931L;

    /**
     * 开始
     */
    private TimePoint from;

    /**
     * 结束
     */
    private TimePoint to;

    /**
     * 长度
     */
    private Long milliSeconds;

    public BudoTimeSpan() {}

    /**
     * 制定时间段长度
     */
    public BudoTimeSpan(Long milliSeconds) {
        this.milliSeconds = milliSeconds;
    }

    /**
     * 指定时间段起止时间
     */
    public BudoTimeSpan(TimePoint from, TimePoint to) {
        this.from = from;
        this.to = to;
    }

    /**
     * 指定时间段起止时间
     */
    public BudoTimeSpan(Date from, Date to) {
        this(Time.when(from), Time.when(to));
    }

    /**
     * 时间段转换为毫秒数
     */
    public Long toMilliSeconds() {
        if (null == this.milliSeconds) {
            synchronized (this) {
                if (null == this.milliSeconds) {
                    if (null != this.from && null != this.to) {
                        Long fromMilliSeconds = from.toMilliSeconds();
                        Long toMilliSeconds = to.toMilliSeconds();
                        if (null != fromMilliSeconds && null != toMilliSeconds) {
                            this.milliSeconds = toMilliSeconds - fromMilliSeconds;
                        }
                    }
                }
            }
        }
        return this.milliSeconds;
    }

    /**
     * 转为秒数 ，可用 intValue() 舍弃余量
     */
    public Double toSeconds() {
        if (null == this.toMilliSeconds()) {
            return null;
        }

        return this.toMilliSeconds() / 1000.00;
    }

    /**
     * 转为分钟数 ，可用 intValue() 舍弃余量
     */
    public Double toMinutes() {
        if (null == this.toMilliSeconds()) {
            return null;
        }

        return this.toSeconds() / 60;
    }

    /**
     * 转为小时数 ，可用 intValue() 舍弃余量
     */
    public Double toHours() {
        if (null == this.toMilliSeconds()) {
            return null;
        }

        return this.toMinutes() / 60;
    }

    /**
     * 转为天数，可用 intValue() 舍弃余量
     */
    public Double toDays() {
        if (null == this.toMilliSeconds()) {
            return null;
        }

        return this.toHours() / 24;
    }

    @Override
    public Double toMonths() {
        if (null == this.toMilliSeconds()) {
            return null;
        }

        return this.toDays() / 30;
    }

    @Override
    public Double toYears() {
        if (null == this.toMilliSeconds()) {
            return null;
        }

        return this.toMonths() / 12;
    }

    public TimePoint getFrom() {
        return this.from;
    }

    public TimePoint getTo() {
        return this.to;
    }

    public Long getMilliSeconds() {
        return this.milliSeconds;
    }

    public void setFrom(AbstractTimePoint from) {
        this.from = from;
    }

    public void setTo(AbstractTimePoint to) {
        this.to = to;
    }

    public void setMilliSeconds(Long milliSeconds) {
        this.milliSeconds = milliSeconds;
    }

    public String toString() {
        String str = super.toString();
        if (null == this.milliSeconds) {
            str += ", from=" + this.from;
            str += ", to=" + this.to;
        } else {
            str += ", " + this.milliSeconds + " milliSeconds";
        }

        if (null != this.toMilliSeconds()) {
            str += ", " + this.toDays().intValue() + "天 ";
            str += (this.toHours().intValue() - (24 * this.toDays().intValue())) + "小时 ";
            str += (this.toMinutes().intValue() - (60 * this.toHours().intValue())) + " 分钟";
        }

        return str;
    }
}
